AWS WAFを使うためシステムにCloudFrontを導入した時の注意点まとめ
はじめに
こんにちは植木和樹@上越妙高オフィスです。先日AWSよりAWS WAFというファイアウォール機能が提供されました。
WAFの設定方法はすでに弊社ブログで紹介されています。
WAFを利用するためにはHTTP/HTTPSリクエストがCloudFrontを経由する必要があります。そこで本日は実際社内で利用しているシステム(ELB+EC2構成)をWAF対応させるため、CloudFrontを設定した際の注意点をまとめてみたいと思います。
環境について
- 現在のサイトはhttps://www.example.comでアクセスしています
- 通信にはHTTPSを利用しています(HTTPは利用していない)
- ドメインの管理はRoute53を使っています
現在の環境
CloudFrontを入れた後の環境
ELB での注意点
ELBにオリジン用の名前を新たにつける
例えばこれまでwww.example.comというドメインでアクセスしていた場合は、www-origin.example.comのような別名でもアクセスできるようにします。これはCloudFrontからELBへアクセスする際に必要になるため、CloudFrontを設定する前にRoute53で新しいレコードを作成しておきましょう。
そしてhttps://www-origin.example.comで現在のサイトが表示できるか確認しておきます。もし表示されない場合はSSL証明書の問題か、EC2のhttpdサーバーの問題が考えられます。
オリジン用のSSL証明書を用意する
HTTPSで利用しているサイトなので、CloudFrontをELBの前段に入れる場合もCloudFront → ELB間はHTTPSで通信させたいと思います。
ELBにワイルドカード証明書(*.example.com)を利用している場合はwww.example.comでもwww-origin.example.comでもHTTPSでの通信ができます。しかしサーバー名指定の証明書を利用している場合は、別途 www-origin.example.com 用のSSL証明書を入手する必要があります。
新たにSSL証明書の購入する場合は費用がかかります。またELBのHTTPS(tcp/443)に設定できるSSL証明書は1つだけ(www.example.com用だけ)です。その場合はwww-origin.example.com用に新たなELBを用意してあげる必要がありますので注意してください。
EC2 での注意点
VirtualHost の設定を確認する
ELBでのHTTPS設定ができた場合でもサイトが正しく表示されない場合は、特定のホスト名でないと目的のサイトが表示されないようになっているのかもしれません。(VirtualHostでDocumentRootを変えているなど)
サイトによっては、rpmでインストールされた httpd.conf を極力変更せず、/etc/httpd/conf.d/virtualhost.conf のようにサイト固有の設定を分けている場合があります。その場合はwww-origin.example.comでもサイトが表示されるよう設定を追加してください。
CloudFront での注意点
おかしな挙動をしたらキャッシュコントロールを見直す
CloudFrontはCDNですので、デフォルト設定では可能な限りページをキャッシュします。ところが動的なページでCloudFrontを経由させると「ログインできない」「画面が遷移されない」などの問題が発生します。
今回はあくまでもWAFを利用するのが目的ですので、キャッシュ効果は控えめにしておきしょう。キャッシュ設定はBehaviorsタブで行います。主な確認ポイントは下記4箇所です。
Forward Headers: None(デフォルト)
HTTPのリクエストヘッダーでアプリケーションの挙動を変えている場合はキャッシュによる不具合が出るかもしません。マルチデバイス対応でブラウザの種類(User-Agent)を判別している場合はAllに設定を変えてください。今回はPCブラウザ専用のサイトですのでNoneにしました。
Object Caching:Use Origin Cache Headers(デフォルト)
キャッシュの有効期限はCloudFrontで上書きせず、オリジナルのものをそのまま利用することにします。
Forward Cookies:None → All
画面遷移情報をCookieに持たせるシステムがあるので、Cookieをオリジンに送らないと画面が切り替わらないといった症状がでることがあります。
Forward Query Strings:No → Yes
これも上記と同様です。クエリー文字列に画面情報を渡すシステムで不具合がでた場合はYesにしましょう。
CloudFrontとELBはHTTPSで通信する
今回のシステムではすべてのリクエストをHTTPSで行っています。CloudFrontに移行する際にもCloudFront → ELB間は(HTTPでなく)HTTPSを利用するようにしました。
CloudFrontがオリジンと通信するための設定はOriginsタブで行います。
Original Domain Name: www-origin.example.com
CloudFrontがオリジンにアクセスする際のドメイン名を指定します。前述の通りHTTPSで通信するため、SSL証明書が有効なドメイン名を設定する必要がります。
Origin Protocol Policy:Match Viewer
Match Viewerにすることで、クライアントのプロトコルがHTTPならCloudFront → ELBもHTTPを使い、クライアントがHTTPSでアクセスしてきたらCloudFrontもHTTPSを使うようになります。
Viewer Protocol Policy: Redirect HTTP to HTTPS
上記のMatch Viewerに加え、クライアントがHTTPでアクセスしたら強制的にHTTPSを使うようリダイレクトさせることで、CloudFront → ELB間には必ずHTTPSを利用させることができます。
まとめ
キャッシュをなるべく使わないことで、システムの挙動は極力変えずにCloudFrontを利用するためのポイントについて整理してみました。これまでCloudFrontを使っていなかったけどWAF機能を使うために導入してみたい、という方の参考になれば幸いです。
ところでWAF機能がでたことで、CloudFrontはキャッシュ目的のサービスだけでなく、レイヤー7の挙動を調整するためのサービスという位置づけが明確になったような気がします。最初にWAFを見た時に「どうしてELBで設定できないんだろう?」と疑問に思いましたが、ELBはレイヤー4/CloudFrontはレイヤー7と機能分けしていくのだなと考え直しました。(Pathベースでリクエストを送り先ノードを切り替えるL7 LoadBalancingとか)
今後構築するシステムについては、拡張性のためにも「まずCloudFrontを入れる」という方向になるのかもしれませんね。